vLastObjectListUpdate = 0.25
vLastFilterUpdate = 0.25
-- local _, reaction = pcall(UnitReaction, "player", object)
ccR.Objects = {
	Clear_Tables =
	function()
		--local startTime = debugprofilestop()
		ccR.table_empty(ccR_Enemies_Within_44)
		ccR.table_empty(ccR_Enemies_Within_16)
		ccR.table_empty(ccR_Enemies_Within_12)
		ccR.table_empty(ccR_Enemies_Within_10)
		ccR.table_empty(ccR_Enemies_Within_8)
		ccR.table_empty(ccR_Enemies)
		ccR.table_empty(ccR_Enemies_In_Combat)
		ccR.table_empty(ccR_Totems)
		ccR.table_empty(ccR_Friendly)
		--print(format("Clearing Tables executed in %f ms", debugprofilestop()-startTime))
	end,
	phelpsCollect =
	function()
		local count = ObjectCount()
		local cacheDuration = 0.1
		local resultCache = { }
		local resultCacheSync = { }
		for i = 1, count do
			local now = time()
			local object = ObjectWithIndex(i)
			local value = false
			if resultCache[object] and resultCacheSync[object] and ( now - resultCacheSync[object] < cacheDuration ) then
				value = resultCache[object]
			else
				value = ExpensiveOperation(object)
				resultCache[object] = value
				resultCacheSync[object] = now
			end
		end
	end,
	Collect = 
	function()
		--local startTime = debugprofilestop()
		ccR.Objects.Clear_Tables()
		local Pointer = {
			Count = nil,
			Index = nil,
			Distance = nil,
		}
		Pointer.Count = ObjectCount()
		for i = 1, Pointer.Count do
			Pointer.Index = ObjectWithIndex(i)
			if ObjectIsType(Pointer.Index, ObjectTypes.Unit)
			and ccR.Unit.Exists(Pointer.Index)
			and ccR.Unit.Distance(Pointer.Index, "player") <= 50
			then
				Pointer.Distance = ccR.Unit.Distance(Pointer.Index, "player")
				ccR.Objects.Totem(Pointer.Index)
				if ccR.Objects.Valid(Pointer.Index, nil) then
					if ccR.Unit.Is.Attackable(Pointer.Index, "player") then
						ccR.Objects.Enemies.All(Pointer.Index)
						ccR.Objects.Enemies.InCombat(Pointer.Index)
						ccR.Objects.Enemies.Distance(Pointer.Index, Pointer.Distance)
					else
						ccR.Objects.Friendly(Pointer.Index, Pointer.Distance)
					end
				end
			end
		end
		--print(format("Collect executed in %f ms", debugprofilestop()-startTime))
	end,
	----
	----
	----
	Valid =
	function(Pointer, type)
		if not ObjectIsType(Pointer, ObjectTypes.Unit)
		or not ccR.Unit.Exists(Pointer)
		or ccR.Unit.NPCID(Pointer) == 40603
		or ccR.tblIgnoreCreatureType[UnitCreatureType(Pointer)]
		or ccR.tblIgnoreNPC[ccR.Unit.NPCID(Pointer)]
		or ccR.Sys.IgnoreNPCWithAura(Pointer)
		or UnitCreatureType(Pointer) == "Totem"
		or (type == "enemy" and not ccR.Unit.Is.Attackable(Pointer, "player"))
		or (type == "friend" and (ccR.Unit.Is.Attackable(Pointer, "player") or not ccR.Unit.Is.APlayer(Pointer)))
		then
			return false
		else
			return true
		end
	end,
	Totem =
	function(Pointer)
		-- Is the Pointer a Totem
		if UnitCreatureType(Pointer) == "Totem" then ccR_Totems[#ccR_Totems+1] = Pointer end
	end,
	Friendly = 
	function(Pointer, Distance)
		-- Friendly NPC/Player within 44 yards of player
		local PointerPlayer = ccR.Unit.Is.APlayer(Pointer)
		if (PointerPlayer or (not PointerPlayer and UnitReaction(Pointer, "player") >= 5) and not ccR.Unit.Is.APet(Pointer))
		and Distance <= 44
		and ccR.Unit.Is.APlayer(Pointer)
		then
			ccR_Friendly[#ccR_Friendly+1] = Pointer
		end
	end,
	Enemies = {
		All =
		function(Pointer)
			-- All enemies from Object List
			ccR_Enemies[#ccR_Enemies+1] = Pointer
		end,
		InCombat =
		function(Pointer)
			-- Tapped by Player, Targetting Player or is a Proving Grounds Hostile
			if (ccR.Unit.Is.TappedByPlayer(Pointer) 
				or ccR.Unit.TargetName(Pointer) == ccR.Player.Name() 
				or (select(8,GetInstanceInfo()) == 1148 and	UnitReaction("player", Pointer) <= 4)
				)
			then
				ccR_Enemies_In_Combat[#ccR_Enemies_In_Combat+1] = Pointer
			end
		end,		
		Distance =
		function(Pointer, Distance)
			-- Within range from player
			if Distance <= 44 then ccR_Enemies_Within_44[#ccR_Enemies_Within_44+1] = Pointer end
			if Distance <= 16 then ccR_Enemies_Within_16[#ccR_Enemies_Within_16+1] = Pointer end
			if Distance <= 12 then ccR_Enemies_Within_12[#ccR_Enemies_Within_12+1] = Pointer end
			if Distance <= 10 then ccR_Enemies_Within_10[#ccR_Enemies_Within_10+1] = Pointer end
			if Distance <= 8 then ccR_Enemies_Within_8[#ccR_Enemies_Within_8+1] = Pointer end
		end,
	},
	Count = 
	function(unit, yards, type)
		local vCount = 0
		type = type or "enemy"
		for i = 1, ObjectCount() do
			if ccR.Objects.Valid(ObjectWithIndex(i), type)
			and ccR.Unit.Distance(ObjectWithIndex(i), unit) <= yards
			then
				vCount = vCount + 1
			end
		end
		return vCount
	end,
}
setmetatable(ccR.Objects, ccR)